1. The Field of the Invention
The present invention generally relates to web services. More specifically, the present invention provides for generating a dynamic web service for legacy application components that are not developed to communicate within a web service environment.
2. Background and Related Art
Computer systems and related technology affect many aspects of society. Indeed, the computer system's ability to process information has transformed the way we live and work. Computer systems now commonly perform a host of tasks (e.g., word processing, scheduling, database management, etc.) that prior to the advent of computer systems were performed manually. More recently, computer systems have been coupled to one another to form computer networks over which the computer systems can communicate electronically to share data. Web services have been a driving force in advancing such communications between computer systems and are turning the way we build and use software inside-out.
Web services let applications share data, and-more powerfully-invoke capabilities from other applications without regard to how those applications were built, what operating system or platform they run on, and what devices are used to access them. Web services are invoked over the Internet by means of industry-standard protocols including SOAP (Simple Open Access Protocol), XML (extensible Markup Language), UDDI (Universal Description Discovery Integration), WSDL (Web Service Description Language), etc. Although web services remain independent of each other, they can loosely link themselves into a collaborating group that performs a particular task.
Often, electronic communication on a web service network includes a client computer system (hereafter referred to as a “client”) requesting access to a network service (e.g., web services) at a server computer system (hereinafter referred to as a “server,” “service,” or “web service”). Accordingly, the client sends a request to the service for particular access to its system resources, wherein if the client is authorized and validated, the service responds with a response message providing the desired information. Of course, other messaging patterns between client and service are available and include simple singleton messages as well as more sophisticated multi-message exchanges like, e.g., notifications, solicit-response, pub-sub patterns, polling, kick-push, queuing, and others. Further, these types of communication are governed by various requirements and capabilities defined by both the client and the service in contracts for distributed systems (e.g., web services).
A contract is an expression of visible aspects of a service (or client) behavior. A contract is represented by a mixture of machine-readable and human languages. Besides the obvious opportunity for additional precision, machine-readable languages enable tooling to construct partial service implementations, automate service deployment, audit/validate messages exchanged, manage services, and enable a host of other network-related functions. Due, however, to limitations in the expressive power of machine-readable languages, human languages remain an important component of contracts-principally to describe message and message exchange pattern semantics.
Network Protocol Description Languages (e.g., WSDL) provide an overall wrapper or specification for describing contracts (e.g., web services Contracts) in a common or standard language. Such specifications make it easy for developers and developer tools to create and interpret contracts. These Network Protocol Description Languages (hereinafter referred to as “NPDL”) have extensive tooling suites, which in large part accounts for their popularity.
Prior to the advent of web services, and over many years, a significant number of distributed applications have been written using legacy component based architectures from various vendors (e.g., COM (Component Object Model), DCOM (Distributed Component Object Model), CORBA (Common Object Request Broker Architecture)). With the arrival and advancement of standards based web services, however, there is interest in exposing the business logic from these legacy components as web services. As an example, and irrespective of the approach followed, the intention is typically to take an application component such as the one that supports the following interface:
Interface IStockSystem : IDispatch {HRESULT GetProductDescription([in] BSTR ProductID,[out, retval] BSTR *ProdDesc) ;HRESULT GetProductInventory ([in] BSTR ProductID,[out, retval] short *ProdCount) ;} ;and produced from that component definition, a corresponding web service layer with a couple of operations illustrated in the following WSDL fragment:
< wsdl:portType name=“StockSystem”><wsdl:operation name=“GetProductDescription”><wsdl:input message=“tns:GetProductDescriptionIn” /><wsdl:output message=“tns:GetProductDescriptionOut” /></wsdl:operation><wsdl:operation name=“GetProductInventory”><wsdl:input message= “tns:GetProductInventoryIn” /><wsdl:output message= “tns:GetProductInventoryOut” /></wsdl:operation></wsdl:portType>
To date, there are only a couple of primary patterns or approaches that have been followed for converting or using legacy components within a web service environment. One approach is a migration or modification, which requires a developer to modify the component source code to add web service support. When the application is compiled and executed, the application will start with the appropriate web service support while still allowing traditional clients to connect to the underlying application.
Another approach is a tooling and metadata driven approach, which produces a static wrapping service. Rather than requiring components source code modification, this approach uses a more external approach to examine existing registered metadata for a component to determine the service that component should offer. This produces a static web service wrapper that is external to but, at least initially, consistent with the underlying unmodified component.
Although the above modified and static approaches have enabled the business logic of legacy components to be accessed in a web service environment, there are several shortcomings and problems associated with both of these approaches. For example, since the modified approach requires source code modification—even when there is no desire to change the business—logic this is a development task rather than a simple administrative procedure. Accordingly, such a task is beyond the scope of a typical administrator role and requires an additional skill set. In addition, the development modification to enable web services may not be available using the original coding environment. For instance, in the case of modifying a component written using a legacy language that is no longer supported, the component first has to be ported to a current language. Accordingly, a modification that looks initially like adding an attribute to a method is in fact a migration to a different language, runtime, and development environment.
In the static tooling approach, a problem exists when the underlying component is modified or a new version deployed. In such instance, the change will not automatically be reflected in the wrapping service until the service is regenerated. In addition, for web service operations, there is an-explicit dependency between the service and the underlying component. Accordingly, care must be taken to ensure that the lifetimes of the component and the web service are synchronized (i.e., the wrapping service requires the component to be active and the component requires the wrapper to be active). Further, depending upon the environment and the external nature of the wrapper, there is typically an additional component to be deployed and administered. In other words, if the components are moved to another machine, the wrapper components must also be identified and moved accordingly.
For at least the foregoing reasons, there exists a need for providing web services and business logic for legacy components without requiring a developer to modify the underlying component source code, allowing for component modification or versioning, as well as supporting the explicit dependency between the service and the underlying component.